/**************************************************************
*
* M3D_TRS.H
*
* Transformations based on quaternions support
**************************************************************/

#ifndef _M3D_TRS_H_
#define _M3D_TRS_H_

#pragma once

class m3dTRS {
public:
   m3dV    t;    // translation transform as a 3D vector
   m3dQUAT r;  // rotation transform as a quaternion
   m3dV    s;    // scaling transform as a 3D vector

   m3dTRS (void) {}
   m3dTRS (const m3dV& trans, const m3dQUAT& rotQ, const m3dV& scale) : t(trans), r(rotQ), s(scale) {}
   m3dTRS (const m3dV& trans, const m3dQUAT& rotQ) :      t(trans), r(rotQ), s(m3dVOneXYZ) {}

   void Identity       (void);
   void Invert         (void);
   void Invert         (m3dTRS *res) const;
   void SetTransform   (const m3dV* transVec, const m3dQUAT* rotateQuat, const m3dV* scaleVec);
   void SetTranslation (const m3dV* transVec);
   void SetRotation    (const m3dQUAT* rotateQuat);
   void SetScale       (const m3dV* scaleVec);

   void SetMatr        (const m3dMATR *matr);
   void GetMatr        (m3dMATR *matr) const;

   void Transform      (const m3dV *a, m3dV *res) const;
   void Transform      (m3dV *vct) const;
};

/**************************************************************
* m3dMultiplyTrs()
* 
* Note: first scale component is ignored and set to identity!
**************************************************************/
__INLINE void m3dMultiplyTrs  (const m3dTRS *a, const m3dTRS *b, m3dTRS *res)
{
   m3dV extraTrans;
   a->r.Transform(&b->t, &extraTrans);
   res->t.x = a->t.x + extraTrans.x;
   res->t.y = a->t.y + extraTrans.y;
   res->t.z = a->t.z + extraTrans.z;
   m3dMultiplyQuat(&a->r, &b->r, &res->r);

   res->s.x = b->s.x;
   res->s.y = b->s.y;
   res->s.z = b->s.z;
}

#define       m3dIsEqualTrs(a, b) m3dIsEqualTrs_A(a, b, M3D_EPSILON)
extern BOOL   m3dIsEqualTrs_A (const m3dTRS *a, const m3dTRS *b, float acc);

extern m3dTRS m3dTrsIdentity;

#endif // _M3D_TRS_H_

//
// End of file 'M3D_TRS.H'
//
